import random
import numpy as np
from src.mutations import byte_mutation, noise_mutation, gauss_approximate_mutation, \
    float_rand_mutation, reverse_mutation


def get_random_seed():
    positive_or_negative = random.randint(0, 1)
    if positive_or_negative == 0:
        seed = random.uniform(-65504, -pow(2, -14))
    else:
        seed = random.uniform(pow(2, -14), 65504)
    return seed


def get_random_seed_tensor(shape):
    size = 1
    for d in shape:
        size *= d
    lst = []
    for i in range(size):
        lst.append(get_random_seed())
    return np.asarray(lst).reshape(shape)


def exec_method_by_index(tensor, index):
    lst = []
    if index < 32:
        type_lst = ['reverse', 'left', 'right', 'left2', 'right2', 'add', 'delete', 'random']
        n = index // 8
        m_type = type_lst[index % 8]
        for x in tensor.flatten():
            if byte_mutation(x, m_type, n) == '':
                return ''
            else:
                lst.append(byte_mutation(x, m_type, n))
    elif index < 33:
        for x in tensor.flatten():
            lst.append(noise_mutation(x))
    elif index < 34:
        for x in tensor.flatten():
            lst.append(gauss_approximate_mutation(x))
    elif index < 41:
        k_lst = [0.1, 0.25, 0.3, 0.5, 0.6, 0.75, 0.9]
        n = index - 34
        k = k_lst[n]
        for x in tensor.flatten():
            lst.append(float_rand_mutation(x, k))
    else:
        for x in tensor.flatten():
            lst.append(reverse_mutation(x))
    return np.asarray(lst).reshape(tensor.shape)
